package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.heima.common.constants.WemediaConstants;
import com.heima.common.exception.CustomException;
import com.heima.feign.article.IArticleClient;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.GreenScanService;
import com.heima.wemedia.service.WmNewsAutoScanService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
@SuppressWarnings("all")
public class WmNewsAutoScanServiceImpl3  {
    @Autowired
    private WmNewsMapper wmNewsMapper;
    @Autowired
    private GreenScanService greenScanService;
    @Autowired
    private WmUserMapper wmUserMapper;
    @Autowired
    private WmChannelMapper wmChannelMapper;
    @Autowired
    private IArticleClient iArticleClient;
    /**
     * 自媒体文章审核
     *
     * @param id
     */
    public void autoScanWmNews(Integer id) {
        //1、先根据id查找自媒体中的文章
        WmNews wmNews = wmNewsMapper.selectById(id);
        //2、提取文章中的内容呢和图片
        //2.1、非空校验
        if (wmNews == null || StringUtils.isEmpty(wmNews.getContent())) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //2.2、提取
        Map<String, Object> map = extarctTextAndImage(wmNews);
        //3、审核文本
        boolean isScanText = ScanText((String) map.get("text"), wmNews);
        if (!isScanText) return; //审核失败 直接返回
        //4、审核图片
        boolean isScanImage = ScanImage((List<String>) map.get("image"), wmNews);
        if (!isScanImage) return; //审核失败 返回
        //5、（审核通过）远程调用article微服务，保存文章 返回文章id
       ResponseResult responseResult = saveArticle(wmNews);
        //6、判断是否成功，成功就保存文章id到自媒体的文章表中
        if (responseResult.getCode() == 200) {
            //设置文章id 成功则修改文章
            wmNews.setArticleId((Long) responseResult.getData());
            updateWmNews(wmNews,WmNews.Status.PUBLISHED.getCode(),"审核成功");
        }else  throw new RuntimeException("WmNewsAutoScanServiceImpl - 文章审核，保存app端相关文章数据失败");
    }

    /**
     * 远程调用文章微服务
     * @param wmNews
     * @return
     */
    private ResponseResult saveArticle(WmNews wmNews) {
        //1、准备一个dto
        ArticleDto dto = new ArticleDto();
        //2、拷贝属性
        BeanUtils.copyProperties(wmNews,dto);
        //3、不能拷贝的属性
        //id
        if (wmNews.getArticleId() != null) {
            //是修改
            dto.setId(wmNews.getArticleId());
        }
        //状态
        dto.setLayout(wmNews.getStatus());
        //作者id
        dto.setAuthorId(wmNews.getUserId().longValue());
        //作者姓名
        WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
        dto.setAuthorName(wmUser.getName());
        //频道名称
        WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
        dto.setChannelName(wmChannel.getName());
        //4、调用远程feign接口 返回结果
        return iArticleClient.savaOrUpdate(dto);
    }

    /**
     * 审核图片
     *
     * @param images
     * @param wmNews
     * @return
     */
    private boolean ScanImage(List<String> images, WmNews wmNews) {
        //1、信号位
        boolean flag = true;
        //2、为空直接返回不用审核
        if (images == null || images.size() == 0) {
            return flag;
        }
        //3、去重
        images = images.stream().distinct().collect(Collectors.toList());
        //4、调用百度云接口审核
        try {
            //4.1、遍历审核
            for (String image : images) {
                //4.2、返回结果
                Map map = greenScanService.scanImage(image);
                //4.3、非空校验
                if (!map.isEmpty()) {
                    if ((int)map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_ILLEGAL) {
                        //违规 修改文章表
                        updateWmNews(wmNews, WmNews.Status.FAIL.getCode(), "文章图片违规");
                        //修改信号位
                        flag = false;
                        //跳出循环
                        break;
                    }
                    if ((int)map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_SUSPECTED) {
                        //违规 修改文章表
                        updateWmNews(wmNews, WmNews.Status.FAIL.getCode(), "文章图片违规");
                        //修改信号位
                        flag = false;
                        //跳出循环
                        break;
                    }
                }
            }
        } catch (Exception e) {
            flag = false;
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 审核文本
     *
     * @param text
     * @return
     */
    private boolean ScanText(String text, WmNews wmNews) {
        //1、信号位
        boolean flag = true;
        //2、为空直接返回true
        if (text == null) {
            return flag;
        }
        //3、调用百度云接口进行审核
        try {
            Map map = greenScanService.scanText(text);
            //3.1、非空校验
            if (!map.isEmpty()) {
                if ((int) map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_ILLEGAL) {
                    //违规 修改文章表
                    updateWmNews(wmNews, WmNews.Status.FAIL.getCode(), "文章内容违规");
                    //修改信号位
                    flag = false;
                }
                if ((int) map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_SUSPECTED) {
                    //疑似违规 修改文章表
                    updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "疑似违规，需要人工审核");
                    //信号位
                    flag = false;
                }
            }
        } catch (Exception e) {
            flag = false;//抛异常也说明审核有问题
            e.printStackTrace();
        }
        //返回信号位
        return flag;
    }

    /**
     * 修改文章
     *
     * @param wmNews
     * @param type
     * @param reason
     */
    private void updateWmNews(WmNews wmNews, short type, String reason) {
        wmNews.setType(type);
        wmNews.setReason(reason);
        wmNewsMapper.updateById(wmNews);
    }

    /**
     * 提取文字和图片
     *
     * @param wmNews
     * @return
     */
    private Map<String, Object> extarctTextAndImage(WmNews wmNews) {
        //1、先创建两个容器保存文本 以及图片
        StringBuilder stringBuilder = new StringBuilder(wmNews.getTitle());
        stringBuilder.append(wmNews.getLabels()); //标题以及标签也要审核
        List<String> imageList = new ArrayList<>();
        //2、遍历提取文本
        //2.1、先解析成json数组
        JSONArray jsonArray = JSON.parseArray(wmNews.getContent());
        //2.2、遍历数组
        for (Object json : jsonArray) {
            //2.3、转为jsonObject对象处理
            JSONObject jsonObject = JSON.parseObject(json.toString());
            //2.4、判断是文本还是图片
            if (jsonObject.get("type").equals("text")) {
                //文本
                stringBuilder.append(jsonObject.get("value").toString());
            }
            if (jsonObject.get("type").equals("image")) {
                //图片
                imageList.add(jsonObject.get("value").toString());
            }
        }
        //3、存入map集合
        Map<String, Object> map = new HashMap<>();
        map.put("text", stringBuilder.toString());
        map.put("image", imageList);
        return map;
    }
}
